﻿using Cofe.Core.Interfaces;
using Cofe.Core.Property;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cofe.Core.Filter
{
    [EntryFilter("root")]
    public class RootEntryFilter : EntryFilterBase, IRootEntryFilter
    {
        void init(IPropertyHost rootDirectory, string id = "root")
        {
            SupportedMatchType = MatchType.MatchSubEntry | MatchType.MatchThisEntry;
            _rootDirectory = rootDirectory;
        }

        static string checkParsePath(string parsePath)
        {
            return parsePath.Replace('/', '\\');
        }

        public RootEntryFilter(IPropertyHost rootDirectory, string id = "root")
            : base(rootDirectory.Behaviors.GetProperty(CofeProperties.FullParseName).ValueAsString, id)
        {
            init(rootDirectory, id);
        }

        public RootEntryFilter(IPathParser[] pathParsers, string parsePath, string id = "root")
            : base(checkParsePath(parsePath), id)
        {            
            var rootDirectory = CofeServices.PathParserManager.Behaviors.TryParsePath(
                   Value, ParsableType.ParsePath, EntryConstructionFlags.Default);            
            init(rootDirectory, id);
        }

        public RootEntryFilter(string parsePath, string id = "root")
            : this(
            CofeServices.ServiceLocater.FindAllServices<IPathParser>().ToArray(),
            checkParsePath(parsePath), id)
        {

        }



        public override MatchType matches(IPropertyHost entry,
            params IOptionFilter[] options)
        {
            MatchType retVal = MatchType.None;

            if (entry.SupportedDefinitions.Contains(
                Cofe.Core.PropertyDefinitions.CofeDirDefinitions, 
                PropertyDefinitionComparer.CompareCategory)
            )
            {
                string entryParseName = entry.Behaviors.GetProperty(CofeProperties.FullParseName).ValueAsString;
                bool sameRoot = entryParseName.StartsWith(Value,
                        StringComparison.CurrentCultureIgnoreCase);
                bool sameDir = sameRoot &&
                    entryParseName.Equals(Value,
                    StringComparison.CurrentCultureIgnoreCase);
                bool isFBFS = entry is ICofeDirectoryInfo &&
                    (entry as ICofeDirectoryInfo).IsFileBasedFS;

                switch (options.GetSearchOption())
                {
                    case SearchOption.AllDirectories:
                        if (sameRoot)
                            retVal |= MatchType.MatchSubEntry;
                        break;
                    case SearchOption.AllDirectoriesAndFileBasedFS:
                        if (sameRoot || isFBFS)
                            retVal |= MatchType.MatchSubEntry;
                        break;
                }
            }
            return retVal | MatchType.MatchThisEntry;
        }

        private IPropertyHost _rootDirectory;

        public IPropertyHost DirectoryPropertyHost { get { return _rootDirectory; } }        

    }
}
